﻿
using System;
using System.Linq;
using iss.sg4210.se18.team6s.jass.DAL;
using iss.sg4210.se18.team6s.jass.DAL.DataAccess.Interfaces;

namespace iss.sg4210.se18.team6s.jass.BL
{
    public class AdvertisementFacade
    {
        IAdvertisement advertisementRepo = null;
        IAdvertisementType advertisementTypeRepo = null;
        IAdvertisementViewLog advertisementViewLogRepo = null;
        AdvertiserFacade advertiserFacade = null;
        public AdvertisementFacade()
        {
            advertisementRepo = DataAccessFactory.Instance.Advertisement;
            advertisementTypeRepo = DataAccessFactory.Instance.AdvertisementType;
            advertisementViewLogRepo = DataAccessFactory.Instance.AdvertisementViewLog;
            advertiserFacade = new AdvertiserFacade();
        }

        public void AddAdvertisement(Advertisement advertisement)
        {
            //check if userId has enough money
            AdvertiserAccount advertiserAccount = advertiserFacade.GetAdvertiserAccount(advertisement.UserId);
            if (advertiserAccount.AccountBalance < advertisement.AdvertisementType.Cost)
                throw new JASSException("Not enough Account balance left for " + advertisement.aspnet_Users.UserName + "!");

            try
            {
                advertisementRepo.AddAdvertisement(advertisement);

                //deduce the amount and update
                advertiserAccount.AccountBalance -= advertisement.AdvertisementType.Cost;
                advertiserFacade.UpdateAdvertiserAccount(advertiserAccount);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_SAVE, ex);
            }
        }

        public object FindAllAdvertisements()
        {
            try
            {
                return advertisementRepo.FindAllAdvertisements();
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_RETRIEVE, ex);
            }
        }

        public IQueryable<Advertisement> FindAllAdvertisementsByUser(System.Guid guid)
        {
            try
            {
                return advertisementRepo.FindAllAdvertisementsByUser(guid);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_RETRIEVE, ex);
            }
        }

        public Advertisement GetAdvertisement(int id)
        {
            try
            {
                return advertisementRepo.GetAdvertisement(id);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_RETRIEVE, ex);
            }
        }

        public void UpdateAdvertisement(Advertisement advertisement)
        {
            try
            {
                advertisementRepo.UpdateAdvertisement(advertisement);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_UPDATE, ex);
            }
        }

        public void DeleteAdvertisement(int id)
        {
            try
            {
                advertisementRepo.DeleteAdvertisement(id);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_DELETE, ex);
            }
        }

        public IQueryable<AdvertisementType> FindAllAdvertisementTypes()
        {
            try
            {
                return advertisementTypeRepo.FindAllAdvertisementTypes();
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_RETRIEVE, ex);
            }
        }

        public AdvertisementType GetAdvertisementType(int id)
        {
            try
            {
                return advertisementTypeRepo.GetAdvertisementType(id);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_RETRIEVE, ex);
            }
        }

        public void AddAdvertisementType(AdvertisementType advertisementType)
        {
            try
            {
                advertisementTypeRepo.AddAdvertisementType(advertisementType);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_SAVE, ex);
            }
        }

        public void UpdateAdvertisementType(AdvertisementType advertisementType)
        {
            try
            {
                advertisementTypeRepo.UpdateAdvertisementType(advertisementType);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_UPDATE, ex);
            }
        }

        public void DeleteAdvertisementType(int id)
        {
            AdvertisementType advertisementType = GetAdvertisementType(id);
            if (advertisementType.Advertisements.Count > 0)
                throw new JASSException("Cannot delete Advertisement Type '" + advertisementType.Type + "'. It has one or more Advertisements!");

            try
            {
                advertisementTypeRepo.DeleteAdvertisementType(id);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_DELETE, ex);
            }
        }

        public GeoArea GetGeographicalAreaByAdvertisementId(int id)
        {
            try
            {
                return advertisementRepo.GetGeographicalAreaByAdvertisementId(id);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_RETRIEVE, ex);
            }
        }

        public Company GetCompanyByAdvertisementId(int id)
        {
            try
            {
                return advertisementRepo.GetCompanyByAdvertisementId(id);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_RETRIEVE, ex);
            }
        }

        public AdvertisementType GetAdvertisementTypeByAdvertisementId(int id)
        {
            try
            {
                return advertisementRepo.GetAdvertisementTypeByAdvertisementId(id);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_RETRIEVE, ex);
            }
        }

        public void AddAdvertisementViewLog(AdvertisementViewLog viewLog)
        {
            try
            {
                advertisementViewLogRepo.AddAdvertisementViewLog(viewLog);
            }
            catch (Exception ex)
            {
                throw new JASSException(JASSConstants.JASS_ERROR_SAVE, ex);
            }
        }
    }
}
